spb/wp-spboucher-ai
Public
1import type { Metadata } from "next";2import Link from "next/link";3import { getLocale } from "@/lib/i18n/server";4import { href, t } from "@/lib/i18n";5import { topicsWithCounts } from "@/lib/papers/queries";6export const revalidate = 300;7export async function generateMetadata(): Promise<Metadata> { const d = t(await getLocale()); return { title: d.topics.title, description: d.topics.lead, alternates: { canonical: "/topics" } }; }8export default async function TopicsPage() {9 const locale = await getLocale(); const d = t(locale); const rows = await topicsWithCounts();10 const domains = rows.filter((r) => r.kind === "domain"), topics = rows.filter((r) => r.kind === "topic" && r.n > 0);11 return (12 <div className="container py-10">13 <h1 className="text-3xl sm:text-4xl">{d.topics.title}</h1><p className="meta mt-2 max-w-3xl">{d.topics.lead}</p>14 <h2 className="text-2xl mt-10 mb-4">{d.topics.domains}</h2>15 <ul className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">{domains.map((x) => <li key={x.slug}><Link href={href(locale, `/topics/${x.slug}`)} className="card p-5 block h-full no-underline hover:shadow-[var(--shadow-lift)] transition-shadow"><span className="flex items-center gap-2"><span className="w-3 h-3 rounded-full" style={{ background: x.accent ?? "var(--navy)" }} /><span className="text-lg text-fg serif">{locale === "fr" ? x.name_fr : x.name_en}</span></span><span className="block text-sm text-fg-2 mt-2 leading-relaxed">{locale === "fr" ? x.description_fr : x.description_en}</span><span className="block meta mt-3">{x.n} {x.n === 1 ? d.topics.paper : d.topics.papers}</span></Link></li>)}</ul>16 <h2 className="text-2xl mt-12 mb-4">{d.topics.all}</h2>17 <ul className="flex flex-wrap gap-2">{topics.map((x) => <li key={x.slug}><Link href={href(locale, `/topics/${x.slug}`)} className="chip no-underline !text-sm !py-1.5 !px-3">{locale === "fr" ? x.name_fr : x.name_en} <span className="font-mono text-fg-3">{x.n}</span></Link></li>)}</ul>18 </div>19 );20}21